package com.contact.util.util.search;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.contact.util.util.collections.Utils;
import com.contact.util.util.filters.DataFilter;
import com.contact.util.util.filters.DateDataFilter;
import com.contact.util.util.filters.DateRangeDataFilter;
import com.contact.util.util.filters.SearchDataFilter;
import com.contact.util.util.filters.WildCardDataFilter;
import com.trg.search.Filter;
import com.trg.search.Search;
import com.trg.search.Sort;

/**
 * This class encapsulates helper functions for creating and transforming <code>Search<code> related 
 * objects for UI and DTO support.
 */
public final class SearchHelper { //NOPMD

    private SearchHelper() {
        // Utility class
    }

    public static Search createSearch(Collection<DataFilter> filters) {
        return createSearch(filters, null);
    }

    public static Search createSearch(Collection<DataFilter> filters, IPaginationInfo pageInfo) {
        return createSearch(filters, pageInfo, null);
    }

    public static Search createSearch(Collection<DataFilter> filters, IPaginationInfo pageInfo, Class<?> searchClass) {
        Search search = createSearch(pageInfo, searchClass);

        if (Utils.hasValues(filters)) {
            search.setFilters(translateFilters(filters));
        }
        return search;
    }

    /**
     * This creates a Search object with no filters. Paging information, sorting, and the class being searched on will
     * all be populated.
     * 
     * @param pageInfo
     *            the PaginationInfo
     * @param searchClass
     *            a SearchClass
     * @return A Search object with no filters set.
     */
    public static Search createSearch(IPaginationInfo pageInfo, Class<?> searchClass) {
        Search search = new Search(searchClass);
        if (pageInfo == null) {
            return search;
        }
        search.setMaxResults(pageInfo.getMaxResults());
        search.setFirstResult(pageInfo.getFirstRow());
        ResultItemSort ris = pageInfo.getResultItemSort();

        if (ris == null || !ris.hasSort()) {
            return search;
        }

        List<Sort> sorts = Utils.newArrayList();
        sorts.add(getSort(ris));
        search.setSorts(sorts);

        return search;
    }

    public static void addFields(Search search, String... fields) {
        if (fields != null && fields.length > 0) {
            for (String field : fields) {
                search.addField(field);
            }
        }
    }

    public static Sort getSort(ResultItemSort ris) {
        return new Sort(ris.getColumn(), !ris.getAscending());
    }

    protected static List<Filter> translateFilters(Collection<DataFilter> dataFilters) { //NOPMD
        List<Filter> filters = new ArrayList<Filter>();
        for (DataFilter dataFilter : dataFilters) {
            Object value = dataFilter.getFilterValue();
            switch (dataFilter.getFilterType()) {
            case DATE:
                filters.addAll(FilterHelper.buildFilter((DateDataFilter<?>) dataFilter));
                break;
            case DATE_RANGE:
                filters.addAll(FilterHelper.buildFilter((DateRangeDataFilter) dataFilter));
                break;
            case SEARCH:
                filters.add(FilterHelper.buildFilter((SearchDataFilter) dataFilter));
                break;
            case WILD_CARD:
                filters.add(FilterHelper.buildFilter((WildCardDataFilter) dataFilter));
                break;
            case EMPTY_VALUE:
                if (value == null) {
                    // If the empty value is null, we do not add a filter, because it means to search all.
                    continue;
                }
                /*filters.add(FilterHelper.buildFilter((EmptyValueDataFilter) dataFilter));*/
                break;
            case ENUM:
                /*filters.add(FilterHelper.buildFilter((EnumDataFilter<?>) dataFilter));*/
                break;
            case SELECTION:
            case REFERENCE_SELECTION:
                if (value == null) {
                    // If the selection value is null, we do not add a filter, because it means to search all.
                    continue;
                }
            default:
                /*filters.add(FilterHelper.buildFilter(dataFilter));*/
                break;
            }
        }
        return filters;
    }

}
